
import { EnumBetResult, EnumBjlResult } from "../../enums/EnumBjlResult";
import { RecmInfo, RoundInfo } from "../ExecutePlan";
import { IMoneyStrategy } from "../IMoneyStrategy";

export interface IBossRabbitMoneyStrategyOption {
    baseMoney: number;
    winStep: number;
    failStep: number;
    prevMoney?: number;
    currentMoney?: number;
    prevPrevMoney?: number;
    maxMoney?: number;
    changeMoney?: number;
}
export class BossRabbitMoneyStrategy implements IMoneyStrategy {
    option: IBossRabbitMoneyStrategyOption;
    baseMoney: number = 100;
    prevMoney: number = 0;
    currentMoney: number = 0;
    orecmV: EnumBjlResult = EnumBjlResult.U;
    orecmMoney: number = 0;
    recmV: EnumBjlResult = EnumBjlResult.U;
    touchMax: boolean = false;
    winStep: number = -1;
    failStep: number = 1;
    constructor(name: string, option?: IBossRabbitMoneyStrategyOption | null) {
        this.strategyName = name;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                baseMoney: 100,
                winStep: 1,
                failStep: -1,
                prevMoney: 0,
                currentMoney: 100,
            };
        }
        this.resetStrategy();
    }
    showMoney(roundInfo?: RoundInfo): [EnumBjlResult, number] {
        if (roundInfo) {
            if (this.orecmV != EnumBjlResult.U && roundInfo.reverse) {
                this.recmV = this.orecmV == EnumBjlResult.Z ? EnumBjlResult.X : EnumBjlResult.Z;
            }
            else{
                this.recmV = this.orecmV;
            }
        }
        return [this.recmV, this.currentMoney];
    }
    resetRecm(): void {
        //this.resetStrategy();
    }
    resetStrategy(): void {
        this.baseMoney = this.option.baseMoney;
        this.orecmV = EnumBjlResult.U;
        this.orecmMoney = 0;
        this.recmV = EnumBjlResult.U;
        this.currentMoney = this.option.currentMoney ?? this.option.baseMoney;
        this.prevMoney = this.option.prevMoney ?? 0;
        this.touchMax = false;
        this.winStep = this.option.winStep;
        this.failStep = this.option.failStep;
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        let recmMoney = this.baseMoney;
        if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {
            if (this.winStep == 0) {
                this.currentMoney = this.option.baseMoney;
                this.prevMoney = this.option.prevMoney ?? 0;
            }
            else if (this.winStep > 0) {
                for (let c = 0; c < this.winStep; c++) {
                    recmMoney = this.currentMoney + this.prevMoney;
                    this.prevMoney = this.currentMoney;
                    this.currentMoney = recmMoney;
                }
            }
            else {
                let wstep = Math.abs(this.winStep);
                if (this.touchMax) wstep = 1;
                for (let c = 0; c < wstep; c++) {
                    recmMoney = this.currentMoney - this.prevMoney;
                    if (recmMoney <= 0) {
                        //recmMoney = 0;
                        this.resetStrategy();
                        break;
                    }
                    this.currentMoney = this.prevMoney;
                    this.prevMoney = recmMoney;
                }
            }

        }
        else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {
            // recmMoney = this.currentMoney - this.prevMoney;
            // this.currentMoney = this.prevMoney;
            // this.prevMoney = recmMoney;
            if (this.failStep == 0) {
                this.currentMoney = this.option.baseMoney;
                this.prevMoney = this.option.prevMoney ?? 0;
            }
            else if (this.failStep > 0) {
                for (let c = 0; c < this.failStep; c++) {
                    recmMoney = this.currentMoney + this.prevMoney;
                    this.prevMoney = this.currentMoney;
                    this.currentMoney = recmMoney;
                }
            }
            else {
                let fstep = Math.abs(this.failStep);
                if (this.touchMax) fstep = 1;
                for (let c = 0; c < fstep; c++) {
                    recmMoney = this.currentMoney - this.prevMoney;
                    if (recmMoney <= 0) {
                        //recmMoney = 0;
                        this.resetStrategy();
                        break;
                    }
                    this.currentMoney = this.prevMoney;
                    this.prevMoney = recmMoney;
                }
            }


        }
        else { }
        let win = Math.abs(recmInfo.summaryInfo.winMoney - recmInfo.summaryInfo.failMoney);
        recmMoney = this.currentMoney;
        if (this.currentMoney < this.baseMoney) {
            // this.currentMoney = this.baseMoney;
            // this.prevMoney = this.option.prevMoney ?? this.baseMoney;
            this.resetStrategy();
        }
        else if (this.option.maxMoney && this.currentMoney > this.option.maxMoney) {
            recmMoney = this.option.maxMoney;
            this.touchMax = true;

        }
        else {
            this.touchMax = false
        }

        this.orecmV = recmV;
        this.orecmMoney = recmMoney;
        if (recmV != EnumBjlResult.U && roundInfo.reverse) {
            recmV = recmV == EnumBjlResult.Z ? EnumBjlResult.X : EnumBjlResult.Z;
        }

        this.recmV = recmV;
        
        return [recmV, recmMoney];
    }

    strategyName: string;
    debugCompoenent: string = "";
    copyValue(valueObj: any): void {
        let obj = valueObj as BossRabbitMoneyStrategy;
        if (obj) {
            this.baseMoney = obj.baseMoney;
            this.prevMoney = obj.prevMoney;
            this.currentMoney = obj.currentMoney;
            this.orecmV = obj.orecmV;
            this.orecmMoney = obj.orecmMoney;
            this.recmV = obj.recmV;
            this.touchMax = obj.touchMax;
            this.winStep = obj.winStep;
            this.failStep = obj.failStep;
        }

    }

    fibo(baseMoney: number, count: number): number {
        if (count == 0 || count == 1) return baseMoney;
        else return this.fibo(baseMoney, count - 1) + this.fibo(baseMoney, count - 2);
    }
    resetBetMoney() {
        this.currentMoney = this.baseMoney;
        this.prevMoney = 0;
    }
}


export interface IBossRabbitMoneyWithMultipleLimit extends IBossRabbitMoneyStrategyOption {
    extendMultiple: number;
}
/**
 * 兔子算法，限制多少倍数
 */
export class BossRabbitMoneyWithMultipleLimitStrategy extends BossRabbitMoneyStrategy {
    extendMultiple: number = 0;
    constructor(name: string, option?: IBossRabbitMoneyWithMultipleLimit) {
        super(name, option);
        this.extendMultiple = option?.extendMultiple ?? 10;
    }
    resetStrategy(): void {
        super.resetStrategy();
    }

    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let [recmV, recmMoney] = super.toMoney(roundInfo, recmInfo, userRecm, baseMoney);
        let win = Math.abs(recmInfo.roundSummaryInfo.winMoney - recmInfo.roundSummaryInfo.failMoney);
        if (this.extendMultiple > 0 && recmV != EnumBjlResult.U && (recmMoney - win) >= (this.baseMoney * this.extendMultiple)) {
            recmMoney = this.baseMoney;
            this.resetBetMoney();
            recmInfo.roundSummaryInfo.resetSummaryInfo();
        }
        return [recmV, recmMoney];
    }
}

export class MaxBossRabbitMoneyStrategy extends BossRabbitMoneyStrategy {
    protected _diffMoney: number;
    public get diffMoney() {
        return this._diffMoney;
    }
    protected _flag: number = 0;
    public get Flag() {
        return this._flag;
    }
    flagStartLimit: number = -100;
    constructor(name: string, option?: IBossRabbitMoneyStrategyOption | null, start?: boolean, flagStartLimit?: number) {
        super(name, option);
        this._diffMoney = 0;
        this.flagStartLimit = flagStartLimit ?? -100;
    }
    resetStrategy(): void {
        super.resetStrategy();
        this._diffMoney = 0;
        this._flag = 0;
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        let recmMoney = this.baseMoney;
        this._diffMoney = recmInfo.roundSummaryInfo.winMoney - recmInfo.roundSummaryInfo.failMoney - recmInfo.roundSummaryInfo.waterMoney;

        if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {
            if (this._flag == 1 && this._diffMoney > 0) {
                recmInfo.roundSummaryInfo.resetSummaryInfo();
                this.resetStrategy();
                return [recmV, this.baseMoney];
            }
            else if (this._flag == 2 && recmInfo.roundSummaryInfo.lwin >= 8) {
                this.resetStrategy();
                return [recmV, this.baseMoney];
            }
            for (let c = 0; c < this.option.winStep; c++) {
                recmMoney = this.currentMoney + this.prevMoney;
                this.prevMoney = this.currentMoney;
                this.currentMoney = recmMoney;
            }


        }
        else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {

            if (this._diffMoney <= this.flagStartLimit && this._diffMoney > -1000) {
                this._flag = 1;
            }
            else if (this._diffMoney <= -1000) {
                this._flag = 2;
            }

            if (recmInfo.roundSummaryInfo.winMoney > recmInfo.roundSummaryInfo.failMoney) {
                recmInfo.roundSummaryInfo.resetSummaryInfo();
                super.resetStrategy();
                return [recmV, this.baseMoney];
            }
            if (this.option.failStep < 0) {
                this.currentMoney = this.baseMoney;
                this.prevMoney = 0;
            }
            else {
                for (let c = 0; c < this.option.failStep; c++) {
                    recmMoney = this.currentMoney - this.prevMoney;
                    if (recmMoney <= 0) {
                        //recmMoney = 0;
                        this.resetStrategy();
                        break;
                    }
                    this.currentMoney = this.prevMoney;
                    this.prevMoney = 0;
                }
            }


        }
        else { }

        let win = Math.abs(recmInfo.summaryInfo.winMoney - recmInfo.summaryInfo.failMoney);
        if (this.currentMoney < this.baseMoney) {
            this.resetStrategy();
        }
        this.recmV = recmV;
        return [recmV, this.currentMoney];
    }

    copyValue(valueObj: any): void {
        let obj = valueObj as MaxBossRabbitMoneyStrategy;
        if (obj) {
            super.copyValue(valueObj);
            this._diffMoney = obj._diffMoney;
            this._flag = obj._flag;
        }

    }
}

export class BossThreeRabiatMoneyStrategy implements IMoneyStrategy {
    option: IBossRabbitMoneyStrategyOption;
    strategyName: string;
    recmV: EnumBjlResult = EnumBjlResult.U;
    recmMoney: number = 0;
    baseMoney: number = 0;
    oneMoney: number = 0;
    twoMoney: number = 0;
    threeMoney: number = 0;
    changeMoney: number = 0;
    winStep: number = 0;
    failStep: number = 0;
    threeStep: boolean = false;
    constructor(name: string, option?: IBossRabbitMoneyStrategyOption | null) {
        this.strategyName = name;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                baseMoney: 100,
                winStep: 1,
                failStep: -1,
                prevPrevMoney: 0,
                prevMoney: 0,
                currentMoney: 100,
                changeMoney: 890
            };
        }
        this.resetStrategy();
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        let recmMoney = this.baseMoney;
        if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {
            if (this.winStep == 0) {
                this.threeMoney = this.baseMoney;
                this.twoMoney = this.option.prevMoney ?? 0;
                this.oneMoney = this.option.prevPrevMoney ?? 0;
            }
            else if (this.winStep > 0) {
                for (let c = 0; c < this.winStep; c++) {
                    if ((this.twoMoney + this.threeMoney) >= (this.option.changeMoney ?? 0) || this.threeStep) {
                        recmMoney = this.oneMoney + this.twoMoney + this.threeMoney;
                        this.threeStep = true;
                        if (this.failStep < 0) {
                            this.failStep = this.option.failStep - 1;
                        }

                    }
                    else {
                        recmMoney = this.threeMoney + this.twoMoney;
                    }
                    this.oneMoney = this.twoMoney;
                    this.twoMoney = this.threeMoney;
                    this.threeMoney = recmMoney;

                }
            }
            else {
                let wstep = Math.abs(this.winStep);
                for (let c = 0; c < wstep; c++) {

                    recmMoney = this.threeMoney - this.twoMoney;
                    if (recmMoney > this.oneMoney) {
                        recmMoney = recmMoney - this.oneMoney;
                    }
                    else if (recmMoney <= this.oneMoney) {
                        recmMoney = this.twoMoney - this.oneMoney;
                        this.winStep = this.option.winStep;
                    }
                    this.threeMoney = this.twoMoney <= 0 ? 0 : this.twoMoney;
                    this.twoMoney = this.oneMoney <= 0 ? 0 : this.oneMoney;
                    this.oneMoney = recmMoney <= 0 ? 0 : recmMoney;

                    recmMoney = this.threeMoney;

                    if (recmMoney <= 0) {
                        //recmMoney = 0;
                        recmMoney = this.threeMoney;
                        this.resetStrategy();
                        break;
                    }

                }
            }

        }
        else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {
            if (this.failStep == 0) {
                this.threeMoney = this.baseMoney;
                this.twoMoney = this.option.prevMoney ?? 0;
                this.oneMoney = this.option.prevPrevMoney ?? 0;
            }
            else if (this.failStep > 0) {
                for (let c = 0; c < this.failStep; c++) {
                    if ((this.twoMoney + this.threeMoney) >= (this.option.changeMoney ?? 0) || this.threeStep) {
                        recmMoney = this.twoMoney + this.threeMoney + this.threeMoney;
                        this.threeStep = true;
                        if (this.winStep > 0) {
                            this.winStep = this.option.winStep + 1;
                        }
                        else if (this.winStep < 0) {
                            this.winStep = this.option.winStep - 1;
                        }
                    }
                    else {
                        recmMoney = this.twoMoney + this.threeMoney;
                    }
                    this.oneMoney = this.twoMoney;
                    this.twoMoney = this.threeMoney;
                    this.threeMoney = recmMoney;
                }
            }
            else {
                let fstep = Math.abs(this.failStep);

                for (let c = 0; c < fstep; c++) {
                    recmMoney = this.threeMoney - this.twoMoney;
                    if (recmMoney > this.oneMoney) {
                        recmMoney = recmMoney - this.oneMoney;
                    }
                    else if (recmMoney <= this.oneMoney) {
                        recmMoney = this.twoMoney - this.oneMoney;
                        this.failStep = this.option.failStep;
                    }
                    this.threeMoney = this.twoMoney <= 0 ? 0 : this.twoMoney;
                    this.twoMoney = this.oneMoney <= 0 ? 0 : this.oneMoney;
                    this.oneMoney = recmMoney <= 0 ? 0 : recmMoney;


                    recmMoney = this.threeMoney;

                    if (recmMoney <= 0) {
                        //recmMoney = 0;
                        this.resetStrategy();
                        recmMoney = this.threeMoney;
                        break;
                    }
                }
            }


        }
        else { }
        this.recmV = recmV;
        this.recmMoney = recmMoney;
        return [recmV, recmMoney];
    }
    showMoney(): [EnumBjlResult, number] {
        return [this.recmV, this.recmMoney];
    }
    resetStrategy(): void {
        this.baseMoney = this.option.baseMoney;
        this.recmV = EnumBjlResult.U;
        this.recmMoney = 0;
        this.oneMoney = this.option.prevPrevMoney ?? 0;
        this.twoMoney = this.option.prevMoney ?? 0;
        this.threeMoney = this.option.currentMoney ?? 0;
        this.winStep = this.option.winStep;
        this.failStep = this.option.failStep;
        this.threeStep = false;
    }
    debugCompoenent: string = "";
    resetRecm(): void {
        //this.resetStrategy();
    }
    copyValue(valueObj: any): void {
        let obj = valueObj as BossThreeRabiatMoneyStrategy;
        if (obj) {
            this.recmV = obj.recmV;
            this.recmMoney = obj.recmMoney;
            this.oneMoney = obj.oneMoney;
            this.twoMoney = obj.twoMoney;
            this.threeMoney = obj.threeMoney;
            this.winStep = obj.winStep;
            this.failStep = obj.failStep;
            this.threeStep = obj.threeStep;
        }
    }
}


export interface IBossRabbitToStepMoneyStrategyOption {
    baseMoney: number;
    rabbitWinStep: number;
    rabbitFailStep: number;
    prevMoney?: number;
    currentMoney?: number;
    changeMoney?: number;
    winStepMoney: number;
    failStepMoney: number;
}
export class BossRabbitToStepMoneyStrategy implements IMoneyStrategy {
    option: IBossRabbitToStepMoneyStrategyOption | null;
    strategyName: string = "";
    recmV: EnumBjlResult = EnumBjlResult.U;
    recmMoney: number = 0;
    baseMoney: number = 0;
    currentMoney: number = 0;
    prevMoney: number = 0;
    rabbitWinStep: number = 0;
    rabbitFailStep: number = 0;
    winStepMoney: number = 0;
    failStepMoney: number = 0;
    constructor(name: string, option?: IBossRabbitToStepMoneyStrategyOption) {
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                baseMoney: 10,
                rabbitWinStep: -1,
                rabbitFailStep: 1,
                prevMoney: 0,
                currentMoney: 10,
                changeMoney: 1440,
                winStepMoney: -500,
                failStepMoney: 500
            };
        }
        this.resetStrategy();
    }

    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        let recmMoney = this.baseMoney;
        if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {
            if (this.currentMoney > (this.option?.changeMoney ?? 0) || (this.winStepMoney > 0 && this.currentMoney == (this.option?.changeMoney ?? 0))) {
                this.currentMoney += this.winStepMoney;
            }
            else {
                if (this.rabbitWinStep == 0) {
                    this.currentMoney = this.baseMoney;
                    this.prevMoney = this.prevMoney ?? 0;
                }
                else if (this.rabbitWinStep > 0) {
                    for (let c = 0; c < this.rabbitWinStep; c++) {
                        recmMoney = this.currentMoney + this.prevMoney;
                        this.prevMoney = this.currentMoney;
                        this.currentMoney = recmMoney;
                    }
                }
                else {
                    let wstep = Math.abs(this.rabbitWinStep);

                    for (let c = 0; c < wstep; c++) {
                        recmMoney = this.currentMoney - this.prevMoney;
                        if (recmMoney <= 0) {
                            //recmMoney = 0;
                            this.resetStrategy();
                            break;
                        }
                        this.currentMoney = this.prevMoney;
                        this.prevMoney = recmMoney;
                    }
                }
            }


        }
        else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {

            if (this.currentMoney > (this.option?.changeMoney ?? 0) || (this.failStepMoney > 0 && this.currentMoney == (this.option?.changeMoney ?? 0))) {
                this.currentMoney += this.failStepMoney;
            }
            else {
                if (this.rabbitFailStep == 0) {
                    this.currentMoney = this.baseMoney;
                    this.prevMoney = this.prevMoney ?? 0;
                }
                else if (this.rabbitFailStep > 0) {
                    for (let c = 0; c < this.rabbitFailStep; c++) {
                        recmMoney = this.currentMoney + this.prevMoney;
                        this.prevMoney = this.currentMoney;
                        this.currentMoney = recmMoney;
                    }
                }
                else {
                    let fstep = Math.abs(this.rabbitFailStep);

                    for (let c = 0; c < fstep; c++) {
                        recmMoney = this.currentMoney - this.prevMoney;
                        if (recmMoney <= 0) {
                            //recmMoney = 0;
                            this.resetStrategy();
                            break;
                        }
                        this.currentMoney = this.prevMoney;
                        this.prevMoney = recmMoney;
                    }
                }

            }


        }
        else { }
        let win = Math.abs(recmInfo.summaryInfo.winMoney - recmInfo.summaryInfo.failMoney);
        recmMoney = this.currentMoney;
        if (this.currentMoney < this.baseMoney) {
            this.resetStrategy();
        }
        this.recmV = recmV;
        return [recmV, recmMoney];
    }
    showMoney(): [EnumBjlResult, number] {
        return [this.recmV, this.recmMoney];
    }
    resetStrategy(): void {
        this.recmV = EnumBjlResult.U;
        this.recmMoney = 0;
        this.baseMoney = this.option?.baseMoney ?? 10;
        this.currentMoney = this.option?.currentMoney ?? 10;
        this.prevMoney = this.option?.prevMoney ?? 0;
        this.rabbitWinStep = this.option?.rabbitWinStep ?? -1;
        this.rabbitFailStep = this.option?.rabbitFailStep ?? 1;
        this.winStepMoney = this.option?.winStepMoney ?? -500;
        this.failStepMoney = this.option?.failStepMoney ?? 500;
    }
    debugCompoenent: string = "";
    resetRecm(): void {
        //this.resetStrategy();
    }
    copyValue(valueObj: any): void {
        let obj = valueObj as BossRabbitToStepMoneyStrategy;
        if (obj) {
            this.recmV = obj.recmV;
            this.recmMoney = obj.recmMoney;
            this.baseMoney = obj.baseMoney;
            this.currentMoney = obj.currentMoney;
            this.prevMoney = obj.prevMoney;
            this.rabbitWinStep = obj.rabbitWinStep;
            this.rabbitFailStep = obj.rabbitFailStep;
            this.winStepMoney = obj.winStepMoney;
            this.failStepMoney = obj.failStepMoney;
        }
    }

}

export class BossRabbitLimitStopMoneyStrategy extends BossRabbitMoneyStrategy {
    runing: boolean = false;
    limit: number = 0;
    recmV: EnumBjlResult = EnumBjlResult.U;
    recmMoney: number = 0;
    constructor(name: string, option?: IBossRabbitMoneyStrategyOption | null, limit?: number) {
        super(name, option);
        this.limit = limit ?? 700;
    }
    resetStrategy(): void {
        super.resetStrategy();
        this.runing = false;
        this.recmV = EnumBjlResult.U;
        this.recmMoney = 0;
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = EnumBjlResult.U;
        let recmMoney = 0;
        if (this.runing) {
            [recmV, recmMoney] = super.toMoney(roundInfo, recmInfo, userRecm, baseMoney);
            return [recmV, recmMoney];
        }
        this.recmV = recmV;
        this.recmMoney = recmMoney;
        return [recmV, recmMoney];
    }
    copyValue(valueObj: any): void {
        super.copyValue(valueObj);
        let obj = valueObj as BossRabbitLimitStopMoneyStrategy;
        if (obj) {
            this.recmV = obj.recmV;
            this.recmMoney = obj.recmMoney;
            this.runing = obj.runing;
        }
    }
}
export interface IResetRecmRabbitOption {
    baseMoney: number;
    winStep: number;
    failStep: number;
    prevMoney?: number;
    currentMoney?: number;
    prevPrevMoney?: number;
    maxMoney?: number;
    changeMoney?: number;
    betArray: EnumBjlResult[];
    startArray: EnumBjlResult[];
}
export class ResetRecmRabbitMoneyStrategy implements IMoneyStrategy {
    option: IResetRecmRabbitOption;
    baseMoney: number = 100;
    prevMoney: number = 0;
    currentMoney: number = 0;
    recmV: EnumBjlResult = EnumBjlResult.U;
    touchMax: boolean = false;
    winStep: number = -1;
    failStep: number = 1;
    betArray: EnumBjlResult[] = [];
    startArray: EnumBjlResult[] = [];
    running: boolean = false;
    constructor(name: string, option?: IResetRecmRabbitOption | null) {
        this.strategyName = name;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                baseMoney: 100,
                winStep: 1,
                failStep: -1,
                prevMoney: 0,
                currentMoney: 100,
                startArray: [],
                betArray: []
            };
        }
        this.resetStrategy();
    }
    showMoney(): [EnumBjlResult, number] {
        return [this.recmV, this.currentMoney];
    }
    resetRecm(): void {
        //this.resetStrategy();
    }
    resetStrategy(): void {
        this.baseMoney = this.option.baseMoney;
        this.recmV = EnumBjlResult.U;
        this.currentMoney = this.option.currentMoney ?? this.option.baseMoney;
        this.prevMoney = this.option.prevMoney ?? 0;
        this.touchMax = false;
        this.winStep = this.option.winStep;
        this.failStep = this.option.failStep;
        this.betArray = this.option.betArray ?? [];
        this.running = false;
        this.startArray = this.option.startArray ?? [];
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {

        let condition = this.startArray.join('');
        let end = roundInfo.results.slice(-this.startArray.length).join("");
        if (!this.running) {
            if (condition == end) {
                this.running = true;
                recmInfo.roundSummaryInfo.resetSummaryInfo();
            }
            else {
                this.recmV = EnumBjlResult.U;
                return [this.recmV, this.currentMoney];
            }
        }


        let recmMoney = this.baseMoney;
        if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {
            if (this.winStep == 0) {
                this.currentMoney = this.option.baseMoney;
                this.prevMoney = this.option.prevMoney ?? 0;

                recmInfo.roundSummaryInfo.resetSummaryInfo();
                if (!(condition == end)) {
                    this.running = false;
                }
            }
            else if (this.winStep > 0) {
                for (let c = 0; c < this.winStep; c++) {
                    recmMoney = this.currentMoney + this.prevMoney;
                    this.prevMoney = this.currentMoney;
                    this.currentMoney = recmMoney;
                }
            }
            else {
                let wstep = Math.abs(this.winStep);
                if (this.touchMax) wstep = 1;
                for (let c = 0; c < wstep; c++) {
                    recmMoney = this.currentMoney - this.prevMoney;
                    if (recmMoney <= 0) {
                        //recmMoney = 0;
                        this.resetStrategy();
                        break;
                    }
                    this.currentMoney = this.prevMoney;
                    this.prevMoney = recmMoney;
                }
            }

        }
        else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {
            // recmMoney = this.currentMoney - this.prevMoney;
            // this.currentMoney = this.prevMoney;
            // this.prevMoney = recmMoney;
            if (this.failStep == 0) {
                this.currentMoney = this.option.baseMoney;
                this.prevMoney = this.option.prevMoney ?? 0;
                recmInfo.roundSummaryInfo.resetSummaryInfo();
                if (!(condition == end)) {
                    this.running = false;
                }
            }
            else if (this.failStep > 0) {
                for (let c = 0; c < this.failStep; c++) {
                    recmMoney = this.currentMoney + this.prevMoney;
                    this.prevMoney = this.currentMoney;
                    this.currentMoney = recmMoney;
                }
            }
            else {
                let fstep = Math.abs(this.failStep);
                if (this.touchMax) fstep = 1;
                for (let c = 0; c < fstep; c++) {
                    recmMoney = this.currentMoney - this.prevMoney;
                    if (recmMoney <= 0) {
                        //recmMoney = 0;
                        this.resetStrategy();
                        break;
                    }
                    this.currentMoney = this.prevMoney;
                    this.prevMoney = recmMoney;
                }
            }


        }
        else { }
        let recmV = EnumBjlResult.U;
        if (this.running) {

            let length = recmInfo.roundSummaryInfo.zCount + recmInfo.roundSummaryInfo.xCount;
            recmV = this.betArray[length % this.betArray.length];
            recmMoney = this.currentMoney;
        }
        if (this.currentMoney < this.baseMoney) {
            // this.currentMoney = this.baseMoney;
            // this.prevMoney = this.option.prevMoney ?? this.baseMoney;
            this.resetStrategy();
        }
        else if (this.option.maxMoney && this.currentMoney > this.option.maxMoney) {
            recmMoney = this.option.maxMoney;
            this.touchMax = true;

        }
        else {
            this.touchMax = false
        }
        this.recmV = recmV;
        return [recmV, recmMoney];
    }

    strategyName: string;
    debugCompoenent: string = "";
    copyValue(valueObj: any): void {
        let obj = valueObj as ResetRecmRabbitMoneyStrategy;
        if (obj) {
            this.baseMoney = obj.baseMoney;
            this.prevMoney = obj.prevMoney;
            this.currentMoney = obj.currentMoney;
            this.recmV = obj.recmV;
            this.touchMax = obj.touchMax;
            this.winStep = obj.winStep;
            this.failStep = obj.failStep;
            this.betArray = obj.betArray;
            this.running = obj.running;
            this.startArray = obj.startArray;
        }

    }

    resetBetMoney() {
        this.currentMoney = this.baseMoney;
        this.prevMoney = 0;
    }
}

export interface ILdRabbitOption {
    baseMoney: number;
    winStep: number;
    failStep: number;
    prevMoney?: number;
    currentMoney?: number;
    prevPrevMoney?: number;
    maxMoney?: number;
    changeMoney?: number;
    stopCount: number;
}
export class LdRabbitMoneyStrategy implements IMoneyStrategy {
    option: ILdRabbitOption;
    recmV: EnumBjlResult = EnumBjlResult.U;
    currentMoney: number = 0;
    prevMoney: number = 0;
    winStep: number = -1;
    failStep: number = 1;
    index: number = 1;
    stepMoney: number = 10;
    stopCount: number = 2;
    runing: boolean = true;
    constructor(name: string, option?: ILdRabbitOption) {
        this.strategyName = name;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                baseMoney: 10,
                winStep: -1,
                failStep: 1,
                prevMoney: 0,
                currentMoney: 10,
                maxMoney: 999999999999,
                changeMoney: 999999999999,
                stopCount: 3,
            };
        }
        this.resetStrategy();
    }
    resetStrategy(): void {
        this.recmV = EnumBjlResult.U;
        this.currentMoney = this.option.currentMoney ?? 0;
        this.prevMoney = this.option.prevMoney ?? 0;
        this.winStep = this.option.winStep;
        this.failStep = this.option.failStep;
        this.stopCount = this.option.stopCount;
    }

    resetRecm(): void {
        this.currentMoney = this.option.baseMoney;
        this.recmV = EnumBjlResult.U;
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        let recmMoney = this.currentMoney;

        if (!this.runing) {
            if (userRecm.summaryInfo.prevResult == EnumBetResult.Success && this.stopCount < 0) {
                this.runing = true;
                userRecm.roundSummaryInfo.resetSummaryInfo();
            }
            else if (userRecm.summaryInfo.prevResult == EnumBetResult.Fail && this.stopCount > 0) {
                this.runing = true;
                userRecm.roundSummaryInfo.resetSummaryInfo();
            }
        }

        else if (this.runing) {
            if (userRecm.summaryInfo.prevResult == EnumBetResult.Success) {
                let winStep = 1;
                for (let i = 0; i < winStep; i++) {
                    recmMoney = this.currentMoney + this.prevMoney;
                    this.prevMoney = this.currentMoney;
                    this.currentMoney = recmMoney;
                }
                if (this.stopCount > 0 && userRecm.roundSummaryInfo.lwin > this.stopCount) {
                    this.runing = false;
                    userRecm.roundSummaryInfo.resetSummaryInfo();
                }

            }
            else if (userRecm.summaryInfo.prevResult == EnumBetResult.Fail) {
                let failStep = 1;
                for (let c = 0; c < this.winStep; c++) {
                    recmMoney = this.currentMoney + this.prevMoney;
                    this.prevMoney = this.currentMoney;
                    this.currentMoney = recmMoney;
                }
                if (this.stopCount < 0 && userRecm.roundSummaryInfo.lfail >= (-this.stopCount)) {
                    this.runing = false;
                    userRecm.roundSummaryInfo.resetSummaryInfo();
                }
            }
        }


        if (recmMoney < this.option.baseMoney) {
            recmMoney = this.option.baseMoney;
        }
        if (!this.runing) {
            recmV = EnumBjlResult.U;
        }


        this.recmV = recmV;
        this.currentMoney = recmMoney;

        return [recmV, recmMoney];
    }
    showMoney(): [EnumBjlResult, number] {
        return [this.recmV, this.currentMoney];
    }
    strategyName: string;
    debugCompoenent: string = "";
    copyValue(valueObj: any): void {
        var obj = valueObj as LdRabbitMoneyStrategy;
        if (obj) {
            this.recmV = obj.recmV;
            this.prevMoney = obj.prevMoney;
            this.currentMoney = obj.currentMoney;
            this.index = obj.index;
            this.failStep = obj.failStep;
            this.winStep = obj.winStep;
            this.stepMoney = obj.stepMoney;
            this.runing = obj.runing;
            this.stopCount = obj.stopCount;

        }
    }
}